import json
import os
import sys
import glob
import time
import urllib.request

api_url = 'https://api.github.com/repos/duckdb/duckdb/'

if (len(sys.argv) < 2):
	print("Usage: [filename1] [filename2] ... ")
	exit(1)

# this essentially should run on release tag builds to fill up release assets and master

repo = os.getenv("GITHUB_REPOSITORY", "")
if repo != "duckdb/duckdb":
	print("Not running on forks. Exiting.")
	exit(0)

ref = os.getenv("GITHUB_REF", '') # this env var is always present just not always used
if ref == 'refs/heads/master':
	print("Not running on master. Exiting.")
	exit(0)
elif ref.startswith('refs/tags/'):
	tag = ref.replace('refs/tags/', '')
else:
	print("Not running on branches. Exiting.")
	exit(0)


print("Running on tag %s" % tag)


token = os.getenv("GH_TOKEN", "")
if token == "":
	raise ValueError('need a GitHub token in GH_TOKEN')

def internal_gh_api(suburl, filename='', method='GET'):
	url = api_url + suburl
	headers = {
		"Content-Type": "application/json",
		'Authorization': 'token ' + token
	}

	body_data = b''
	raw_resp = None
	if len(filename) > 0:
		method = 'POST'
		body_data = open(filename, 'rb')
		headers["Content-Type"] = "binary/octet-stream"
		headers["Content-Length"] = os.path.getsize(local_filename)
		url = suburl # cough

	req = urllib.request.Request(url, body_data, headers)
	req.get_method = lambda: method
	print(f'GH API URL: "{url}" Filename: "{filename}" Method: "{method}"')
	raw_resp = urllib.request.urlopen(req).read().decode()

	if (method != 'DELETE'):
		return json.loads(raw_resp)
	else:
		return {}

def gh_api(suburl, filename='', method='GET'):
	timeout = 1
	nretries = 10
	success = False
	for i in range(nretries+1):
		try:
			response = internal_gh_api(suburl, filename, method)
			success = True
		except urllib.error.HTTPError as e:
			print(e.read().decode()) # gah
		except Exception as e:
			print(e)
		if success:
			break
		print(f"Failed upload, retrying in {timeout} seconds... ({i}/{nretries})")
		time.sleep(timeout)
		timeout = timeout * 2
	if not success:
		raise Exception("Failed to open URL " + suburl)
	return response


# check if tag exists
resp = gh_api('git/ref/tags/%s' % tag)
if 'object' not in resp or 'sha' not in resp['object'] : # or resp['object']['sha'] != sha
	raise ValueError('tag %s not found' % tag)

resp = gh_api('releases/tags/%s' % tag)
if 'id' not in resp or 'upload_url' not in resp:
	raise ValueError('release does not exist for tag ' % tag)


# double-check that release exists and has correct sha
# disabled to not spam people watching releases
# if 'id' not in resp or 'upload_url' not in resp or 'target_commitish' not in resp or resp['target_commitish'] != sha:
# 	raise ValueError('release does not point to requested commit %s' % sha)

# TODO this could be a paged response!
assets = gh_api('releases/%s/assets' % resp['id'])

upload_url = resp['upload_url'].split('{')[0] # gah
files = sys.argv[1:]
for filename in files:
	if '=' in filename:
		parts = filename.split("=")
		asset_filename = parts[0]
		paths = glob.glob(parts[1])
		if len(paths) != 1:
			raise ValueError("Could not find file for pattern %s" % parts[1])
		local_filename = paths[0]
	else:
		asset_filename = os.path.basename(filename)
		local_filename = filename

	# delete if present
	for asset in assets:
		if asset['name'] == asset_filename:
			gh_api('releases/assets/%s' % asset['id'], method='DELETE')

	resp = gh_api(f'{upload_url}?name={asset_filename}', filename=local_filename)
	if 'id' not in resp:
		raise ValueError('upload failed :/ ' + str(resp))
	print("%s -> %s" % (local_filename, resp['browser_download_url']))
